package learnjava.concur.chapter6;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerArray;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

public class P017 {

    public static void main(String[] args) {

        int len = 5;

        demo(
                ()->new int[len],
                (arr)-> arr.length,
                (arr,idx)-> arr[idx]++,
                (arr)-> System.out.println(Arrays.toString(arr))
        );

        demo(
                ()-> new AtomicIntegerArray(len),
                (arr)-> arr.length(),
                (arr,index)-> arr.getAndIncrement(index),
                (arr)-> System.out.println(arr)
        );

    }

    /**
     * 使用函数式接口，提高复用性
     * Supplier<T> 无参，一个返回值
     * Function<T,Integer>， 一个参数，一个结果
     * BiConsumer<T,Integer>， 两个参数，无返回
     * Consumer<T>， 一个参数，无返回
     */
    private static <T> void demo (
            Supplier<T> arraySupplier,
            Function<T,Integer> lengthFun,
            BiConsumer<T,Integer> putConsumer,
            Consumer<T> printConsumer
    ){
        List<Thread> ts = new ArrayList<>();
        T array = arraySupplier.get();
        int length = lengthFun.apply(array);
        for (int i = 0; i < length; i++) {
            ts.add(new Thread(()->{
                for (int j = 0; j < 10000; j++) {
                    putConsumer.accept(array,j%length); //把j%length处的值自增
                }
            }));
        }
        ts.forEach(Thread::start); //start和join分开循环，否则相当于串行执行
        for (Thread t : ts) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        printConsumer.accept(array);
    }

}
